#lang racket

(define (id x) x)

(define (inc x) (+ x 1))

(define (accumulate-rec filter combiner null-value term a next b)
  (if (> a b)
      null-value
      (if (filter a) 
          (combiner (term a) (accumulate-rec filter combiner null-value term (next a) next b))
          (accumulate-rec filter combiner null-value term (next a) next b))))

(define (accumulate-iter filter combiner null-value term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (if (filter a) 
            (iter (next a) (combiner result (term a)))
            (iter (next a) result))))
  (iter a null-value))

(define (odd-sum term a next b) (accumulate-rec odd? + 0 term a next b))

(define (odd-product term a next b) (accumulate-rec odd? * 1 term a next b))

;(define (prime-sum a b) (accumulate-iter prime? + 0 id a inc b))

(define (gcd-one-product n)
  (define (gcd-one? x) (= (gcd n x) 1))
  (accumulate-iter gcd-one? * 1 id 1 inc (- n 1)))

(odd-sum id 1 inc 10)

(odd-product id 1 inc 6)

(gcd-one-product 10)